var l = [
  {
    name : '1. The beginning...',
    tile : [
      "   ~~~~~ ",
      "    ~#+  ",
      "~~~+~~~  ",
      "~   ~~~ ~",
      "~~+~~~~+~",
      "~        "
    ],
    init : [1,1]
  },
  {
    name : '2. Quite Easy',
    tile : [
      "   ++++  ",
      " # ~~~~  ",
      "   ~+++  ",
      "+~+~+~~+~",
      "     ~   ",
      "     +   "
    ],
    init : [8,0]
  },
  {
    name : '3. Chess',
    tile : [
      " + + + + ",
      "+ + + + +",
      " + + + + ",
      "+ + + + +",
      " + + +#+ ",
      "+ + + + +"
    ],
    init : [0,0]
  },
  {
    name : '4. Konigsberg',
    tile : [
      "         ",
      "~+~+~~~+~",
      "     ~   ",
      "     +   ",
      "~+~+~~~+~",
      "     #   "
    ],
    init : [5,5]
  },
  {
    name : '5. Checkmate',
    tile : [
      " + + + + ",
      "+ +#~ + +",
      " + + + + ",
      "+ + + + +",
      " + + +#+ ",
      "+ + + ~ +"
    ],
    init : [0,0]
  },
  {
    name : '6. Detour',
    tile : [
      "         ",
      "~+~~~~~  ",
      "~+ + ~#+~",
      "~+ + ~#~ ",
      "~+~~~~+~+",
      "~ + + +  "
    ],
    init : [8,3]
  },
  {
    name : '7. Happy',
    tile : [
      "  +   +  ",
      " +#+ +#+ ",
      "  +   +  ",
      "+       +",
      " +     + ",
      "  +++++  "
    ],
    init : [5,2]
  },
  {
    name : '8. Territories',
    tile : [
      "  +   +  ",
      " ~  +~ ~ ",
      "+  ~   + ",
      "+ +  #  +",
      " ~ ~+~ ~ ",
      "# +   +  "
    ],
    init : [8,0]
  }
];

function trystep(dx,dy)
{
  return function() {
    g.trystep(dx,dy);
  };
}

var g = {

  start : function(lvl) {
    this.level = lvl;
    this.map = l[lvl].tile;
    this.pos = null;
    this.steppedOn = {};
    this.steppedOff = {};
    this.step(l[lvl].init);
    $('#lyt-help').toggle(lvl == 0);
    $('#gameover').hide();
    this.render();
  },

  step : function(xy) {
    if (this.pos)
      this.steppedOff[this.pos.join()] = true;
    this.pos = xy;
    this.steppedOn[this.pos.join()] = true;

    if (this.map[xy[1]].charAt(xy[0]) == '#' && !this.remaining()) {
      this.win();
    }
  },

  remaining : function() {

    for (var y = 0; y < 6; ++y) {
      for (var x = 0; x < 9; ++x) {
	if (this.map[y].charAt(x) == ' ' && !([x,y].join() in this.steppedOn))
	  return true;
      }
    }

    return false;
  },

  render : function() {
    for (var y = 0; y < 6; ++y) {
      for (var x = 0; x < 9; ++x) {
        var t = this.map[y].charAt(x),
           $t = g.$t[y][x];

	var xy = [x,y].join();

	$t.attr('class',[
	  'tile',
	  [x,y].join() == this.pos.join() ? 'show' : '',
	  t == ' ' && xy in this.steppedOn ? 'grass' : '',
	  t == ' ' && !(xy in this.steppedOn) ? 'dirt' : '',
	  t == '~' || t == '+' && xy in this.steppedOff ? 'water' : '',
	  t == '+' && !(xy in this.steppedOff) ? 'wood' : '',
	  t == '#' ? 'stone' : ''
	].join(' '));

      }
    }
  },

  win : function()
  {
    if (this.level + 1 == l.length) {
      $('#gameover').fadeIn('slow');
    } else {
      this.start(this.level+1);
    }
  },

  up: trystep(0,-1),
  down: trystep(0,1),
  left: trystep(-1,0),
  right: trystep(1,0),

  trystep : function (dx,dy)
  {
    var x = this.pos[0] + dx;
    var y = this.pos[1] + dy;

    if (x < 0) return;
    if (x > 8) return;
    if (y < 0) return;
    if (y > 5) return;

    var t = this.map[y].charAt(x);

    if (t == '~' || t == '+' && [x,y].join() in this.steppedOff) return;

    this.step([x,y]);
    this.render();
  }
};


$(function(){

    var $world   = $('#lyt-world');
    g.$t = [];

    $(document).keydown(function(e){
      var keys = { 37 : 'left', 38 : 'up', 39 : 'right', 40 : 'down' };
      if (e.keyCode in keys) {
	g[keys[e.keyCode]]();
      }
    });

    $('#restart').click(function(){g.start(g.level);});

    $.each(l,function(i,l) {
      $('<option>').attr('value',i).text(l.name).appendTo('#select');
    });

    $('#select').change(function(){
      g.start(parseInt($('#select option:selected').val()));
      $(this).blur();
    });

    for (var y = 0; y < 6; ++y ) {
      var r = [];
      for (var x = 0; x < 9; ++x) {
	r.push($('<div class="tile"><div class="tile-img"/><div class="tile-sel"/></div>').appendTo($world));
      }
      g.$t.push(r);
    }

    $('<div class="clr"/>').appendTo($world);

    g.start(0);
});